package cn.com.dingtek.genius.manager.server.service;

import cn.com.dingtek.genius.manager.server.repository.db.entity.CompanyBase;
import cn.com.dingtek.genius.manager.server.repository.db.entity.DeviceBase;
import cn.com.dingtek.genius.manager.server.repository.db.entity.DeviceInstruct;
import cn.com.dingtek.genius.manager.server.repository.db.entity.DeviceReport702;
import cn.com.dingtek.genius.manager.server.repository.db.manager.CompanyBaseManager;
import cn.com.dingtek.genius.manager.server.repository.db.manager.DeviceBaseManager;
import cn.com.dingtek.genius.manager.server.repository.db.manager.DeviceInstructManager;
import cn.com.dingtek.genius.manager.server.repository.db.manager.DeviceReport702Manager;
import cn.com.dingtek.genius.manager.server.support.DeviceSocket;
import cn.com.dingtek.genius.manager.server.support.DeviceType;
import cn.com.dingtek.genius.manager.server.support.PlatformType;
import cn.com.dingtek.genius.manager.server.utils.MybatisPlusUtil;
import cn.com.dingtek.genius.manager.server.utils.Verify;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Slf4j
@Service
public class DevicebindService {
    @Autowired
    private DeviceBaseManager deviceBaseManager;

    @Autowired
    private CompanyBaseManager companyBaseManager;

    @Autowired
    private DeviceReport702Manager deviceReport702Manager;

    @Autowired
    private DeviceInstructManager deviceInstructManager;

    public JSONObject list(DeviceBase param, int currentPage, int pageSize) {
        QueryWrapper<DeviceBase> query = null;
        if (param.getCompanyId() == null) {
            query = Wrappers.<DeviceBase>query().isNotNull("company_id");
        } else {
            query = Wrappers.<DeviceBase>query().eq("company_id", param.getCompanyId());
        }

        if (param != null) {
            query = MybatisPlusUtil.customEqQuery(query, "device_type", param.getDeviceType());
            query = MybatisPlusUtil.customEqQuery(query, "device_socket", param.getDeviceSocket());
            query = MybatisPlusUtil.customEqQuery(query, "platform_type", param.getPlatformType());
            query = MybatisPlusUtil.customLikeQuery(query, "imei", param.getImei());
        }

        IPage<DeviceBase> deviceBasePage = deviceBaseManager.page(new Page<DeviceBase>(currentPage, pageSize).setDesc("id"), query);

        List<JSONObject> records = deviceBasePage.getRecords().stream()
                .map(item -> {
                    JSONObject jsonObject = (JSONObject) JSON.toJSON(item);
                    Optional<DeviceType> deviceType = DeviceType.valueOf(item.getDeviceType());
                    Optional<DeviceSocket> deviceSocket = DeviceSocket.valueOf(item.getDeviceSocket());
                    Optional<PlatformType> platformType = PlatformType.valueOf(item.getPlatformType());

                    CompanyBase companyBase = companyBaseManager.getById(item.getCompanyId());

                    return jsonObject.fluentPut("deviceType_desc", deviceType.isPresent() ? deviceType.get().toString() : null)
                            .fluentPut("deviceSocket_desc", deviceSocket.isPresent() ? deviceSocket.get().toString() : null)
                            .fluentPut("platformType_desc", platformType.isPresent() ? platformType.get().toString() : null)
                            .fluentPut("company_name", companyBase == null ? "--" : companyBase.getCompanyName());
                }).collect(Collectors.toList());
        return new JSONObject().fluentPut("total", deviceBasePage.getTotal())
                .fluentPut("records", records);
    }

    public JSONObject info(Long id) {
        Verify.isTrue(id != null && id > 0, "设备不存在");
        DeviceBase deviceBase = deviceBaseManager.getById(id);
        Verify.notNull(deviceBase, "设备不存在");
        Verify.isTrue(deviceBase.getCompanyId() != null, "设备未分配企业");

        CompanyBase companyBase = companyBaseManager.getById(deviceBase.getCompanyId());


        JSONObject result = (JSONObject) JSON.toJSON(deviceBase);
        result.fluentPut("deviceTypeDesc", DeviceType.valueOf(deviceBase.getDeviceType()).get().getDesc())
                .fluentPut("deviceSocketDesc", DeviceSocket.valueOf(deviceBase.getDeviceSocket()).get().getDesc())
                .fluentPut("platformTypeDesc", PlatformType.valueOf(deviceBase.getPlatformType()).get().getDesc())
                .fluentPut("companyName", companyBase == null ? "--" : companyBase.getCompanyName());

        return result;
    }

    public JSONObject reportList(Long deviceBaseId, int currentPage, int pageSize) {
        QueryWrapper<DeviceReport702> query = Wrappers.<DeviceReport702>query().eq("device_base_id", deviceBaseId);
        IPage<DeviceReport702> page = deviceReport702Manager.page(new Page<DeviceReport702>(currentPage, pageSize).setDesc("id"), query);
        return new JSONObject().fluentPut("total", page.getTotal())
                .fluentPut("records", page.getRecords());
    }

    public JSONObject instructList(DeviceInstruct param, int currentPage, int pageSize) {
        QueryWrapper<DeviceInstruct> query = Wrappers.<DeviceInstruct>query().eq("device_base_id", param.getDeviceBaseId());
        IPage<DeviceInstruct> page = deviceInstructManager.page(new Page<DeviceInstruct>(currentPage, pageSize).setDesc("id"), query);
        return new JSONObject().fluentPut("total", page.getTotal())
                .fluentPut("records", page.getRecords());
    }

    public void instructSend(DeviceInstruct param, String currentAccount, Date now) {
        deviceInstructManager.save(DeviceInstruct.builder()
                .deviceBaseId(param.getDeviceBaseId())
                .instructContent(param.getInstructContent())
                .instructResult(0)
                .userAccount(currentAccount)
                .ctime(now)
                .utime(null)
                .build());
    }
}
